/**
 * 校园智能快递集散系统
 * 程序设计基础课程设计(2024级)
 *
 * 本文件包含系统公共数据类型定义
 */

#ifndef SYSTEM_TYPES_H
#define SYSTEM_TYPES_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>

 // 常量定义
#define MAX_USERNAME_LEN 20
#define MAX_PASSWORD_LEN 20
#define MAX_PHONE_LEN 15
#define MAX_ADDRESS_LEN 100
#define MAX_DESCRIPTION_LEN 200
#define MAX_SHELF_CODE_LEN 10
#define MAX_PICKUP_CODE_LEN 10
#define MAX_ORDER_ID_LEN 20
#define MAX_NOTIFICATION_ID_LEN 100
#define MAX_PACKAGE_TYPES 6
#define MAX_FLOOR_TYPES 20

// 权限控制常量定义
#define PERM_USER_MGMT      0x0001  // 用户管理权限
#define PERM_PACKAGE_ADD    0x0002  // 包裹入库权限
#define PERM_PACKAGE_PICKUP 0x0004  // 包裹出库权限
#define PERM_PACKAGE_QUERY  0x0008  // 包裹查询权限
#define PERM_SHELF_MGMT     0x0010  // 货架管理权限
#define PERM_SYSTEM_MGMT    0x0020  // 系统管理权限
#define PERM_STATS_VIEW     0x0040  // 查看统计数据权限
#define PERM_LOG_VIEW       0x0080  // 查看日志权限
#define PERM_ALL            0xFFFF  // 所有权限

// 用户类型枚举
typedef enum {
    USER_STUDENT = 1,   // 普通用户(学生)
    USER_VIP = 2,       // VIP用户
    USER_COURIER = 3,   // 快递员
    USER_STAFF = 4,     // 驿站工作人员
    USER_ADMIN = 5      // 系统管理员
} UserType;

// 包裹类型枚举
typedef enum {
    PACKAGE_NORMAL = 1,     // 普通包裹
    PACKAGE_LARGE = 2,      // 大件包裹
    PACKAGE_FRAGILE = 3,    // 易碎包裹
    PACKAGE_FRESH = 4,      // 生鲜/冷链包裹
    PACKAGE_VALUABLE = 5,   // 贵重包裹
    PACKAGE_STORAGE = 6     // 寄存包裹
} PackageType;

// 包裹状态枚举
typedef enum {
    STATUS_RECEIVED = 1,    // 已入库
    STATUS_NOTIFIED = 2,    // 已通知
    STATUS_PICKED = 3,      // 已取走
    STATUS_EXPIRED = 4,     // 超期未取
    STATUS_DAMAGED = 5,     // 已破损
    STATUS_LOST = 6,        // 已丢失
    STATUS_RETURNED = 7,    // 已退回
    STATUS_WRONGPICKED = 8, // 错误领取
    STATUS_PENDING_RETURN = 9    // 待退回（新增）
} PackageStatus;

// 错误码定义
typedef enum {
    OK = 0,                 // 成功
    ERR_INVALID_PARAM = -1, // 无效参数
    ERR_NO_PERMISSION = -2, // 无权限
    ERR_NOT_FOUND = -3,     // 未找到
    ERR_DUPLICATE = -4,     // 重复
    ERR_MEMORY = -5,        // 内存错误
    ERR_FILE_IO = -6,       // 文件IO错误
    ERR_SHELF_FULL = -7,    // 货架已满
    ERR_INVALID_STATUS = -8,// 无效状态
    ERR_SYSTEM = -99        // 系统错误
} ErrorCode;

// 通知类型枚举
typedef enum {
    NOTIFICATION_ARRIVAL = 1,      // 包裹到达通知
    NOTIFICATION_PICKUP = 2,       // 包裹取走通知
    NOTIFICATION_REMINDER = 3,     // 取件提醒通知
    NOTIFICATION_DAMAGED = 4,      // 包裹损坏通知
    NOTIFICATION_LOST = 5,         // 包裹丢失通知
    NOTIFICATION_RETURNED = 6,     // 包裹退回通知
    NOTIFICATION_WRONG_PICKUP = 7, // 错误取件通知
    NOTIFICATION_SYSTEM = 8        // 系统通知
} NotificationType;

// 前向声明
struct Notification;
struct Package;

// 用户结构体
typedef struct User {
    char username[MAX_USERNAME_LEN];          // 用户名
    char password[MAX_PASSWORD_LEN];          // 密码
    char phone[MAX_PHONE_LEN];                // 手机号
    char address[MAX_ADDRESS_LEN];            // 地址
    UserType type;                            // 用户类型
    int vipLevel;                             // VIP等级(如适用)
    unsigned int permissions;                 // 权限位掩码
    int fee;                                  // 费用

    struct User* next;                        // 链表指针
} User;

// 包裹结构体
typedef struct Package {
    char orderId[MAX_ORDER_ID_LEN];           // 订单号
    char receiverPhone[MAX_PHONE_LEN];        // 收件人手机号
    char senderPhone[MAX_PHONE_LEN];          // 寄件人手机号
    char sendername[MAX_USERNAME_LEN];        // 寄件人姓名
    char description[MAX_DESCRIPTION_LEN];    // 包裹描述
    PackageType type;                         // 包裹类型
    PackageStatus status;                     // 包裹状态    
    char pickupCode[MAX_PICKUP_CODE_LEN];    // 取件码
    char receiveTime[64];                     // 入库时间
    char notifyTime[64];                      // 通知时间
    char pickupTime[64];                      // 取件时间
    float weight;                             // 包裹重量
    float fee;                                // 费用
    int notificationStatus;                   //是否通知
    char shelfCode[64];                       //货架编号
    // 退货相关字段
    char returnReason[MAX_DESCRIPTION_LEN];     // 退货原因
    char returnMarkedTime[20];                  // 标记退货时间
    char returnMarkedBy[MAX_USERNAME_LEN];      // 标记退货操作员
    char returnHandledTime[20];                 // 处理退货时间
    char returnHandledBy[MAX_USERNAME_LEN];     // 处理退货快递员
    char returnCourier[MAX_DESCRIPTION_LEN];    // 处理退回的快递公司
    char returnCourierContact[MAX_PHONE_LEN];   // 快递公司联系方式
    char returnTrackingNo[MAX_ORDER_ID_LEN];    // 退回物流单号

    // 取件相关信息
    char pickedUpByPhone[MAX_PHONE_LEN];      // 实际取件人手机号
    char pickedUpByUsername[MAX_USERNAME_LEN]; // 实际取件人用户名
    int isProxyPickup;                        // 是否代取，1表示是，0表示否
    char proxyRelation[MAX_DESCRIPTION_LEN];  // 代取关系说明(如同学、室友等)
    char expressmanPhone[MAX_PHONE_LEN];      // 快递员电话
    struct Package* next;                     // 链表指针
} Package;

// 货架结构体
typedef struct Shelf {
    char code[MAX_SHELF_CODE_LEN];            // 货架编码
    int capacity[MAX_FLOOR_TYPES];            // 总容量，索引表示对应层数，capacity[0]表示货架的层数
    int occupied[MAX_FLOOR_TYPES];            // 已占用数量
    int supportTypes[MAX_PACKAGE_TYPES];      // 支持的包裹类型数组，1表示支持
    int isSpecialized;                        // 是否为专用货架
    struct Shelf* next;                       // 链表指针
    int codeCounter[MAX_FLOOR_TYPES];         // 用于每一层取件码的计数
} Shelf;

// 通知结构体
typedef struct Notification {
    char notificationID[MAX_NOTIFICATION_ID_LEN]; // 通知ID
    char receiverPhone[MAX_PHONE_LEN];        // 接收者手机号
    char message[MAX_DESCRIPTION_LEN];        // 通知内容
    char orderID[MAX_ORDER_ID_LEN];           // 订单号  
    time_t createTime;                        // 创建时间
    int notificationType;                     // 通知种类
    int isRead;                               // 是否已读,0-未读，1-已读
    struct Notification* next;                // 链表指针
} Notification;

// 操作日志结构体
typedef struct Log {
    char username[MAX_USERNAME_LEN];          // 操作用户
    char operation[MAX_DESCRIPTION_LEN];      // 操作描述
    time_t operationTime;                     // 操作时间
    struct Log* next;                         // 链表指针
} Log;

// 系统数据结构
typedef struct {
    User* userList;                           // 用户链表
    Package* packageList;                     // 包裹链表
    Package* packageTail;                     // 包裹链表尾端
    Shelf* shelfList;                         // 货架链表
    Shelf* shelfTail;                         // 货架链表尾端
    int hjnum;                                // 货架数量
    Log* logList;                             // 日志链表
    unsigned int rolePermissions[5];          // 角色默认权限
    Notification* notificationList;           // 通知链表 可能不需要
} SystemData;

// 系统初始化与基础功能

/**
 * 初始化系统数据
 *
 * @return 初始化的系统数据结构指针
 */
SystemData* initSystem();

/**
 * 从文件加载系统数据
 *
 * @param data 系统数据结构指针
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode loadSystemData(SystemData* data);

/**
 * 将系统数据保存到文件
 *
 * @param data 系统数据结构指针
 * @return 成功返回OK，失败返回错误码
 */
ErrorCode saveSystemData(SystemData* data);

/**
 * 释放系统所有内存资源
 *
 * @param data 系统数据结构指针
 */
void cleanupSystem(SystemData* data);

/**
 * 权限检查函数
 *
 * @param user 用户指针
 * @param requiredPermission 需要的权限
 * @return 有权限返回1，无权限返回0
 */
int hasPermission(User* user, unsigned int requiredPermission);


/**
 * 显示主菜单z
 *
 * @param currentUser 当前登录用户
 */
void showMainMenu(User* currentUser);

#endif // SYSTEM_TYPES_H